// SingletonBase.h: interface for the CSingletonBase class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SINGLETONBASE_H__982CEDCD_1AA3_4CF6_B02A_1F20B295C00D__INCLUDED_)
#define AFX_SINGLETONBASE_H__982CEDCD_1AA3_4CF6_B02A_1F20B295C00D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

 #define CLASS_UNCOPYABLE(classname) \
     private: \
    classname##(const classname##&); \
     classname##& operator=(const classname##&);


class Mutex
 {
     CLASS_UNCOPYABLE(Mutex)
 public:
     Mutex() :m_csLock() { InitializeCriticalSection(&m_csLock); }
     ~Mutex() { DeleteCriticalSection(&m_csLock); }
     void lock() { EnterCriticalSection(&m_csLock); }
     void unlock() { LeaveCriticalSection(&m_csLock); }
 private:
     CRITICAL_SECTION m_csLock;
 };
 
 class Lock {
     CLASS_UNCOPYABLE(Lock)
 public:
     explicit Lock(Mutex& cs) :m_mutexLock(cs) { m_mutexLock.lock(); }
     ~Lock() { m_mutexLock.unlock(); }
 private:
     Mutex& m_mutexLock;
 };

template<class T>
class Singleton
 {
	   CLASS_UNCOPYABLE(Singleton)
	public:
	   static T* Instance()
	   { // Unique point of access
	         if (0 == m_instance)
			 {
	            Lock lock(m_mutex);
	             if (0 == m_instance) 
				 {
	                 m_instance = new T();
//	                 atexit(Destroy);
	             }
	         }
	         return m_instance;
	     }

	   static void Destroy() 
	   { // Destroy the only instance
		   if ( m_instance != 0 ) 
		   {
			   delete m_instance;
			   m_instance = 0;
		   }
	   }
	 protected:
	     Singleton(){}
	     ~Singleton(){}
	 private:
	     
	     static Mutex m_mutex;
	     static T * volatile m_instance; // The one and only instance
 };
	 
	 template<class T>
	 Mutex Singleton<T>::m_mutex;
	 
	 template<class T>
	 T * volatile Singleton<T>::m_instance = 0;
	 

#endif // !defined(AFX_SINGLETONBASE_H__982CEDCD_1AA3_4CF6_B02A_1F20B295C00D__INCLUDED_)
